package cn.buk.qms.service;

import cn.buk.api.vaas.dto.ServiceProductResponse;
import cn.buk.api.vaas.service.AirportService;
import cn.buk.common.JsonResult;
import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.tms.dao.ProductBoughtDao;
import cn.buk.tms.dao.ProductDao;
import cn.buk.tms.dao.TransactionDao;
import cn.buk.tms.dto.ServiceProductDto;
import cn.buk.common.util.DateUtil;
import cn.buk.tms.entity.misc.*;
import com.alibaba.fastjson.JSON;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * User: yfdai
 * Date: 14-4-17
 * Time: 下午11:07
 * To change this template use File | Settings | File Templates.
 * @author yfdai
 */
@Component
public class ProductServiceImpl extends BaseAbstractService implements ProductService {

    private final static Logger logger = LogManager.getLogger(ProductServiceImpl.class);

    @Autowired
    private ProductDao productDao;

    @Autowired
    private ProductBoughtDao productBoughtDao;

    @Autowired
    private TransactionDao transactionDao;

    @Override
    public List<Product> findAll() {
        return productDao.findAll();
    }

    @Override
    public Product getProductByCode(String productCode) {
        return productDao.getByCode(productCode);
    }

    /**
     * 查找产品的购买记录
     */
    @Override
    public ProductBought getProductBoughtByCode(final int enterpriseId, final String productCode) {
        Product product = productDao.getByCode(productCode);
        if (product == null) {
          return new ProductBought();
        }

        ProductBought pb = productBoughtDao.getByProductId(product.getId(), enterpriseId);

        if (pb == null) {
            pb = new ProductBought();
            pb.setProduct(product);
        }

        return pb;
    }

    /**
     *
     * @param enterpriseId 购买企业
     * @param productCode  产品代码
     * @return
     *      0: 系统错误，没有产品信息
     *      1: 余额不足
     *      100: 购买成功
     */
    @Override
    public int buyProduct(final int enterpriseId, final String productCode, final int buyQuantity, final int buyDays) {
        int retCode = 0;

        Product product = productDao.getByCode(productCode);
        if (product == null) {
          return retCode;
        }

        ProductBought pb = getProductBoughtByCode(enterpriseId, productCode);

        //要付的费用
        int fee = 0;
        if (product.getChargeUnit() == Product.CHARGE_UNIT_BY_DAY) {
            fee = product.getRetailPrice() * buyDays;
            pb.setRemark("续 " + product.getProductName() + " 费用: " + fee + " (天数:" + buyDays + ").");
        }
        else if (product.getChargeUnit() == Product.CHARGE_UNIT_BY_QUANTITY_PER_DAY) {
            fee = product.getRetailPrice() * buyQuantity * buyDays;
            pb.setRemark("续 " + product.getProductName() + " 费用: " + fee + "(数量: " + buyQuantity + ",天数: " + buyDays + ").");
        }
        else if (product.getChargeUnit() == Product.CHARGE_UNIT_BY_MONTH) {
            fee = product.getRetailPrice() * buyQuantity;
            pb.setRemark("续 " + product.getProductName() + " 费用: " + fee + "(时长: " + buyQuantity + "月).");
        }

        pb.setBoughtCount(buyQuantity);

        if (pb.getEndTime() == null || pb.getEndTime().getTime() < DateUtil.getCurDate().getTime()) {
          pb.setEndTime(DateUtil.addDays(DateUtil.getCurDate(), buyDays-1)); //要包括当天
        } else {
          pb.setEndTime(DateUtil.addDays(pb.getEndTime(), buyDays));
        }


        if (fee > 0) {

            EnterpriseBalance entBalance = userDao.getEnterpriseBalance(enterpriseId);

            if (entBalance.getBitcoinBalance() < fee) {
              retCode = 1;
            } else {
                retCode = transactionDao.buyProductByPoints(pb, fee, 0);
            }
        } else {
            retCode = transactionDao.buyProductByPoints(pb, fee, 0);
        }


        return retCode;
    }

    /**
     * 购买产品
     * @param priceMode 0: 零售价格，1：批发价格
     */
    @Override
    public JsonResult buyProduct(int enterpriseId, String productCode, final int priceMode) {
        if (!Product.ITINERARY_PRINT_CODE.equalsIgnoreCase(productCode)
                && !Product.ETERM_AUTO_SS.equalsIgnoreCase(productCode)) {
            return JsonResult.createJsonResult(-1, "此产品暂时不可以在线购买");
        }

        Product product = productDao.getByCode(productCode);
        if (product == null) {
          return JsonResult.createJsonResult(-2, "无此产品数据");
        }


        ProductBought pb = productBoughtDao.getByProductId(product.getId(), enterpriseId);

        if (Product.ITINERARY_PRINT_CODE.equalsIgnoreCase(productCode)) {
            // 行程单免费购买, 最晚到2021-01-31
            if (pb == null) {
                // 新购买
                pb = new ProductBought();
                pb.setEnterpriseId(enterpriseId);
                pb.setProductCode(productCode);
                pb.setProduct(product);
                pb.setBoughtCount(1);

                Date expireDate = DateUtil.addDays(DateUtil.getCurDate(), 10);
                Date lastDate = DateUtil.createDate(2021, 1, 31);
                if (expireDate.getTime() > lastDate.getTime()) {
                    expireDate = lastDate;
                }

                pb.setEndTime(expireDate); //要包括当天
            } else {
                int spanDays = DateUtil.getPastDays(pb.getEndTime(), DateUtil.getCurDate());
                if (spanDays > 5) {
                    return JsonResult.createJsonResult(-3, "还没到可续费时间");
                }

                Date expireDate;
                if (spanDays < 0) {
                    expireDate = DateUtil.addDays(DateUtil.getCurDate(), 10); //要包括当天
                } else {
                    expireDate = DateUtil.addDays(pb.getEndTime(), 10); //要包括当天
                }

                Date lastDate = DateUtil.createDate(2021, 1, 31);
                if (expireDate.getTime() > lastDate.getTime()) {
                    expireDate = lastDate;
                }

                pb.setEndTime(expireDate); //要包括当天
            }

            transactionDao.buyProductByPoints(pb, 0, 0);
        } else if (Product.ETERM_AUTO_SS.equalsIgnoreCase(productCode)) {
            // 购买追位
            final int minCount;
            final int fee;

            if (priceMode == 0) {
                // 零售价购买
                minCount = 1;
                fee = product.getRetailPrice();
            } else {
                //priceMode == 1
                // 批发价
                minCount = product.getMinWholesaleCount();
                fee = product.getWholesalePrice() * minCount;
            }

            if (pb == null) {
                // 新购买
                pb = new ProductBought();
                pb.setEnterpriseId(enterpriseId);
                pb.setProductCode(productCode);
                pb.setProduct(product);
                pb.setBoughtCount(1);
                pb.setEndTime(DateUtil.addDays(DateUtil.getCurDate(), minCount*30)); //要包括当天
            } else {
                int spanDays = DateUtil.getPastDays(pb.getEndTime(), DateUtil.getCurDate());
                if (spanDays < 0) {
                    pb.setEndTime(DateUtil.addDays(DateUtil.getCurDate(), minCount * 30)); //要包括当天
                } else {
                    pb.setEndTime(DateUtil.addDays(pb.getEndTime(), minCount * 30)); //要包括当天
                }
            }

            pb.setRemark("购买" + product.getProductName() + " " + DateUtil.formatDate(pb.getEndTime(), "yyyy-MM-dd"));

            try {
                transactionDao.buyProductByCash(pb, fee, 0);
            } catch (RuntimeException ex) {
                logger.error(ex.getMessage());
                return JsonResult.createJsonResult(-100, ex.getMessage());
            }
        }

        return JsonResult.createJsonResult(1);
    }

    @Override
    @Secured({RoleInfo.ROLE_ADMIN})
    public JsonResult createTieInProduct(TieInProduct p) {

        if (p.getProductName() == null || p.getProductName().trim().length() == 0) {
            return JsonResult.createJsonResult(-1, "产品名称必填");
        }

        int retCode = productDao.createTieInProduct(p);
        return JsonResult.createJsonResult(retCode);
    }

    @Override
    public List<ServiceProductDto> searchTieInProducts(int enterpriseId, CommonSearchCriteria sc) {
        List<TieInProduct> products = productDao.searchTieInProducts(enterpriseId, sc);

        List<ServiceProductDto> dtos = new ArrayList<>();
        for(TieInProduct info: products) {
            ServiceProductDto dto = new ServiceProductDto();
            BeanUtils.copyProperties(info, dto);

            dtos.add(dto);
        }

        return dtos;
    }

    @Override
    @Secured({"ROLE_ADMIN"})
    public JsonResult deleteProduct(int enterpriseId, int id) {
        int retCode = productDao.deleteTieInProduct(enterpriseId, id);
        return JsonResult.createJsonResult(retCode);
    }

    @Override
    public ServiceProductDto searchProductById(int enterpriseId, int id) {
        TieInProduct product = productDao.getTieInProductById(id);
        if (product == null || product.getEnterpriseId() != enterpriseId) {
          return null;
        }

        ServiceProductDto dto = new ServiceProductDto();
        BeanUtils.copyProperties(product, dto);

        return dto;
    }

    @Override
    public List<ServiceProductDto> searchRemoteServiceProducts(final int enterpriseId) {
        List<ServiceProductDto> list = new ArrayList<>();

        ServiceProductResponse response = getServiceProducts(enterpriseId);
        if (response.getErrorCode() == 0) {
            //调用成功
            for(cn.buk.api.vaas.dto.ServiceProductDto apiDto: response.getDatas()) {
                ServiceProductDto dto = new ServiceProductDto();
                BeanUtils.copyProperties(apiDto, dto);

                list.add(dto);
            }
        } else {
            //TODO 发送企业微信通知 yfdai 2019-12-18
            logger.error(response.getErrorCode() + ": " + response.getErrorMsg());
        }

        list = list.stream().filter(t -> t.getProductType() == 3).collect(Collectors.toList());

        return list;
    }

    private ServiceProductResponse getServiceProducts(final int enterpriseId) {
        final String key = "api_vaas_services_" + enterpriseId;

        String jsonStr = redisDao.getStr(key, StandardCharsets.UTF_8);

        if (jsonStr == null) {
            AirportService airportService = createAirportService(enterpriseId);
            ServiceProductResponse response = airportService.getServiceProducts();

            if (response.getErrorCode() == 0) {
                //接口调用成功，缓存到redis
                jsonStr = JSON.toJSONString(response);
                redisDao.setAndExpire(key, jsonStr.getBytes(StandardCharsets.UTF_8), 30 * 60);
            }

            return response;
        } else {
            logger.info(jsonStr);
            return JSON.parseObject(jsonStr, ServiceProductResponse.class);
        }
    }

}
